package com.dream.mqpushserver.netty;

import com.dream.mqpushserver.annotation.RpcService;
import com.dream.mqpushserver.api.HelloService;
import com.dream.mqpushserver.handler.ServerHandler;
import com.dream.mqpushserver.netty2.RpcDeCoder;
import com.dream.mqpushserver.netty2.RpcEnCoder;
import com.dream.mqpushserver.service.HelloServiceImpl;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;


@Component
public class NettyServe implements SmartLifecycle {

    private static EventLoopGroup bossGroup = null;

    private static EventLoopGroup workGroup = null;

    public static final Map<String,Object> map = new HashMap<>() ;

    @PostConstruct
    public void init(){
        // 模拟注解暴露服务
        map.put(HelloService.class.getName(), new HelloServiceImpl());
    }

    public static Boolean putObject(String clazzName, Object obj){
       return map.put(clazzName, obj) == null;
    }


    @Override
    public void start() {

        System.out.println("mqpush server start .... ");
        bossGroup = new NioEventLoopGroup();

        workGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
//                        pipeline.addLast(new MyProtocolDeCoder(1024 * 1024, 1, 4));
//                        pipeline.addLast(new MyProtocolEnCoder());
//                        pipeline.addLast(new ServerHandler());
                        pipeline.addLast(new RpcDeCoder(65565,1,4));
                        pipeline.addLast(new RpcEnCoder());
                        pipeline.addLast(new NettyServerHandler2());
                    }
                });

        try {
            ChannelFuture sync = bootstrap.bind(10001).sync();

            if (sync.isSuccess()) {
                System.out.println("server started success ...");
            } else {
                System.out.println("server started failed ....");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    @Override
    public void stop() {
        if (workGroup != null) {
            workGroup.shutdownGracefully();
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
    }

    // 只有该方法为false时，才会在初始化bean后执行start()方法
    @Override
    public boolean isRunning() {
        return false;
    }

}
